﻿using System.Drawing;
using System.Drawing.Drawing2D;
using GraphDrawing2.Canvas;
using GraphDrawing2.Core;

namespace GraphDrawing2.V2.Graph.Model
{
    public class ShapeView : IShapeView
    {
        readonly GraphicsPath interior;
        readonly Appearance standard;
        readonly Appearance hovered;
        readonly Appearance selected;
        ShapeModel model;

        public ShapeView()
        {
            interior = new GraphicsPath();
            standard = new Appearance();
            standard.Color = Color.WhiteSmoke;
            standard.Border.Color = Color.Firebrick;
            hovered = new Appearance();
            hovered.CopyFrom(standard);
            hovered.Border.Width = 2.0f;
            selected = new Appearance();
            selected.CopyFrom(hovered);
            selected.Color = Color.DodgerBlue;
        }

        public void Dispose()
        {
            interior.Dispose();
        }

        public void Initialize(ShapeModel model)
        {
            this.model = model;
            if (model.ShapeType == ShapeType.Rectangle)
                interior.AddRectangle(new RectangleF(0, 0, model.Width, model.Height));
            else
                interior.AddEllipse(new RectangleF(0, 0, model.Width, model.Height));
        }

        public bool Contains(PointF point)
        {
            return interior.IsVisible(point);
        }

        public void Render(DrawingContext dc)
        {
            var g = dc.graphics;
            var state = g.Save();
            try
            {
                g.TranslateTransform(model.Position.X, model.Position.Y);
                var appearance = GetAppearance();
                using (var brush = appearance.CreateBrush())
                    g.FillPath(brush, interior);
                using (var pen = appearance.Border.CreatePen())
                    g.DrawPath(pen, interior);
            }
            finally
            {
                g.Restore(state);
            }
        }

        Appearance GetAppearance()
        {
            if (model.Hints.HasFlag(StateHints.SELECTED))
                return selected;
            if (model.Hints.HasFlag(StateHints.HOVERED))
                return hovered;
            return standard;
        }
    }
}